﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using mBook.DataManager;
using mBook.Models;
using mBook.Utils;


namespace mBook.ViewModels
{
    public class ManagerDataViewModel : mBook.Common.BindableBase
    {
        private static ManagerDataViewModel _dataViewSource = new ManagerDataViewModel();

        public static async Task<ObservableCollection<CategoryviewModel>> getMyEbook()
        {
            //reset data
            _dataViewSource.AllGroups.Clear();

            //add my ebook
            ObservableCollection<EbookViewModel> myEbooks = await EbookViewModel.GetMyEbooks();
            if (myEbooks.Count > 0)
            {
                CategoryviewModel category = new CategoryviewModel(new Category(Constants.MY_EBOOK_ID, "My Ebook", ""));

                foreach (EbookViewModel ebook in myEbooks)
                {
                    ebook.Group = category;
                    category.Items.Add(ebook);
                }

                _dataViewSource.AllGroups.Add(category);

                return _dataViewSource.AllGroups;
            }

            return null;
        }

        public static async Task<ObservableCollection<CategoryviewModel>> GetAllData()
        { 
            

            // Add ebook from server
            EbookList ebookList ;
            CategoryList categoryList;
            try
            {
                 ebookList = await DataService.GetInstance().GetListEbookByTopDownload();
                 categoryList = await DataService.GetInstance().GetListCategories();
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }

            if (categoryList != null)
            {
                foreach (Category c in categoryList.CategoriesList)
                {
                    CategoryviewModel dataCategory = new CategoryviewModel(c);
                    foreach (Ebook e in ebookList.EbooksList)
                    {
                        if (e.CategoryId == c.Id)
                        {
                            EbookViewModel dataEbook = new EbookViewModel(e, dataCategory);
                            dataCategory.Items.Add(dataEbook);
                        }
                    }

                    _dataViewSource.AllGroups.Add(dataCategory);
                }
            }

            

            return _dataViewSource.AllGroups;
        }

        public static  async Task<ObservableCollection<CategoryviewModel>> ResetData()
        {
           // _dataViewSource.AllGroups.Clear();

            return await ManagerDataViewModel.GetAllData();
            
        }

        DownloadStatus statusDownload = new DownloadStatus("");

        public DownloadStatus StatusDownload
        {
            get { return statusDownload; }
            set
            {              
                statusDownload = value;
            }
        }



        public static DownloadStatus GetStatusDownload()
        {
            return _dataViewSource.statusDownload;
        }

        public static void SetStatus(String s)
        {
            _dataViewSource.StatusDownload.Status = s;
        }

        private ObservableCollection<CategoryviewModel> _allGroups = new ObservableCollection<CategoryviewModel>();
        public ObservableCollection<CategoryviewModel> AllGroups
        {
            get { return this._allGroups; }
            
        }

        public static ObservableCollection<CategoryviewModel> getAllGroups()
        {
            return _dataViewSource.AllGroups;
        }

        public static  CategoryviewModel GetGroup(string uniqueId)
        {
            // Simple linear search is acceptable for small data sets
            var matches = _dataViewSource.AllGroups.Where((group) => group.UniqueId.Equals(uniqueId));
            if (matches.Count() == 1) return matches.First();
            return null;
        }

        public static EbookViewModel GetItem(string uniqueId)
        {
            // Simple linear search is acceptable for small data sets
            var matches = _dataViewSource.AllGroups.SelectMany(group => group.Items).Where((item) => item.UniqueId.Equals(uniqueId));
            if (matches.Count() >= 1) return matches.First();
            return null;
        }

        /********* Download ***********/
        private ObservableCollection<EbookViewModel> downloadingEbooks = new ObservableCollection<EbookViewModel>();

        public ObservableCollection<EbookViewModel> DownloadingEbooks
        {
            get { return downloadingEbooks; }
            set { downloadingEbooks = value; }
        }

        public static ObservableCollection<EbookViewModel> GetAllDownloadingEbooks()
        {
            return _dataViewSource.downloadingEbooks;
        }

        public static void AddDownloadingEbook(EbookViewModel Ebook)
        {
            _dataViewSource.DownloadingEbooks.Add(Ebook);
        }

        public static void RemoveDownloadingEbook(EbookViewModel Ebook)
        {
            _dataViewSource.DownloadingEbooks.Remove(Ebook);
        }

        /********* My Ebook **********/
        public static async void AddMyEbook(EbookViewModel ebook)
        {
            EbookViewModel newDataEbook = new EbookViewModel(ebook.EBook, null);
            newDataEbook.UniqueId = Constants.PREFIX_MY_EBOOK_ID + newDataEbook.UniqueId;
            if (_dataViewSource.AllGroups.Count > 0){
                CategoryviewModel _category = _dataViewSource.AllGroups.First();
                if (_category.UniqueId == Constants.MY_EBOOK_ID)
                {
                    newDataEbook.Group = _category;
                    _category.Items.Add(newDataEbook);
                }
                else
                {
                    CategoryviewModel category = new CategoryviewModel(new Category(Constants.MY_EBOOK_ID, "My Ebook", ""));

                    newDataEbook.Group = category;
                    category.Items.Add(newDataEbook);

                    _dataViewSource.AllGroups.Insert(0, category);

                }

                if (ebook.EBook.FilePath != null)
                {
                    String result = await EbookViewModel.SaveEbook(ebook);
                    if (result != "Success")
                    {
                        App.ShowMessage("save database fail");
                    }

                }

                
            }

            await EbookViewModel.SaveEbook(ebook);

        }

        /************** Group by letter ***********/
        public static ObservableCollection<GroupInfoList<EbookViewModel>> GetGroupsByLetter(ObservableCollection<EbookViewModel> listEbooks)
        {
            ObservableCollection<GroupInfoList<EbookViewModel>> groups = new ObservableCollection<GroupInfoList<EbookViewModel>>();

            var query = from item in listEbooks
                        orderby ((EbookViewModel)item).Title
                        group item by ((EbookViewModel)item).Title[0].ToString().ToLower() into g
                        select new { GroupName = g.Key, Items = g };
            foreach (var g in query)
            {
                GroupInfoList<EbookViewModel> info = new GroupInfoList<EbookViewModel>();
                info.Key = g.GroupName.ToUpper();
                foreach (var item in g.Items)
                {
                    info.Add(item);
                }
                groups.Add(info);
            }

            return groups;

        }


    }

    public class GroupInfoList<T> : List<object>
    {

        public object Key { get; set; }


        public new IEnumerator<object> GetEnumerator()
        {
            return (System.Collections.Generic.IEnumerator<object>)base.GetEnumerator();
        }
    }
}
